package com.xb.controller;

import com.xb.entity.ChangePasswordReqVO;
import com.xb.entity.LoginInfo;
import com.xb.entity.User;
import com.xb.service.ILoginInfoService;
import com.xb.service.IUserRoleService;
import com.xb.service.IUserService;
import com.xb.util.JsonData;
import com.xb.util.Result;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * Controller
 * /api/user
 */
@RestController
@RequestMapping("/api/user")
public class UserController {
    @Autowired
    private IUserService userService;
    @Autowired
    private IUserRoleService userRoleService;
    @Autowired
    private ILoginInfoService loginInfoService;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @RequestMapping("/toLogin")
    public Result toLogin(String email, String password, HttpSession session, @RequestParam(defaultValue = "false") boolean rememberMe) {
        Result result = new Result();
        Subject subject = SecurityUtils.getSubject();
        AuthenticationToken token = new UsernamePasswordToken(email, password, rememberMe);
        try {
            subject.login(token);
            session.setAttribute("email",token.getPrincipal().toString());
            result.setStatus(Result.RESPONSE_SUCCESS);
            result.setMessage("登录成功！");
        } catch (UnknownAccountException e) {
            result.setStatus(Result.RESPONSE_FAIL);
            result.setMessage("该用户不存在！");
        } catch (IncorrectCredentialsException e) {
            result.setStatus(Result.RESPONSE_FAIL);
            result.setMessage("密码错误！");
        } catch (AuthenticationException e) {
            result.setStatus(Result.RESPONSE_EXCEPTION);
            result.setMessage("登录失败！请联系管理员 <a href=\"mailto:xb.yang1@outlook.com\">点击这里发送邮件给xb.yang1@outlook.com</a>");
        }
        return result;
    }

    @RequestMapping("/loginInfo")
    public Result loginInfo(@RequestBody JsonData jsonData, HttpServletRequest request, HttpSession session) {
        Result result = new Result();
        String userAgent = request.getHeader("User-Agent");
        String browser = "Unknown";
        String version = "Unknown";

        if (userAgent != null) {
            if (userAgent.contains("MSIE")) {
                browser = "Internet Explorer";
                version = userAgent.substring(userAgent.indexOf("MSIE") + 5, userAgent.indexOf(";", userAgent.indexOf("MSIE")));
            } else if (userAgent.contains("Trident")) {
                browser = "Internet Explorer";
                version = userAgent.substring(userAgent.indexOf("rv") + 3, userAgent.indexOf(")", userAgent.indexOf("rv")));
            } else if (userAgent.contains("Firefox")) {
                browser = "Mozilla Firefox";
                version = userAgent.substring(userAgent.indexOf("Firefox") + 8);
            } else if (userAgent.contains("Chrome")) {
                browser = "Google Chrome";
                version = userAgent.substring(userAgent.indexOf("Chrome") + 7);
            } else if (userAgent.contains("Safari")) {
                browser = "Safari";
                version = userAgent.substring(userAgent.indexOf("Version") + 8, userAgent.indexOf(" ", userAgent.indexOf("Version")));
            } else if (userAgent.contains("Opera")) {
                browser = "Opera";
                version = userAgent.substring(userAgent.indexOf("Version") + 8);
            }
        }

        String email = (String) session.getAttribute("email");
        User user = new User();
        user.setEmail(email);
        user.setUpdateTime(new Date());
        user.setLoginIp(jsonData.getIp());
        user.setLoginDate(new Date());
        User loginUser = userService.selectUserByEmail(email);

        LoginInfo loginInfo = new LoginInfo();
        loginInfo.setLoginIp(jsonData.getIp());
        loginInfo.setLoginBrowser(browser + version);
        loginInfo.setLoginAddress(jsonData.getAdInfo().getProvince().isEmpty() ? jsonData.getAdInfo().getNation() : jsonData.getAdInfo().getProvince() + jsonData.getAdInfo().getCity() + jsonData.getAdInfo().getDistrict());
        loginInfo.setUserId(String.valueOf(loginUser.getId()));
        loginInfo.setDescription(email);
        loginInfo.setCreateDatetime(new Date());
        if (email != null) {
            if (userService.updateUser(user) > 0 && loginInfoService.insertLoginInfo(loginInfo) > 0) {
                result.setStatus(Result.RESPONSE_SUCCESS);
                result.setMessage("登录成功！");
            } else {
                result.setStatus(Result.RESPONSE_FAIL);
                result.setMessage("登录失败！请联系管理员 <a href=\"mailto:xb.yang1@outlook.com\">点击这里发送邮件给xb.yang1@outlook.com</a>");
            }
        } else {
            result.setStatus(Result.RESPONSE_FAIL);
            result.setMessage("登录失败！请联系管理员 <a href=\"mailto:xb.yang1@outlook.com\">点击这里发送邮件给xb.yang1@outlook.com</a>");
        }
        return result;
    }


    @GetMapping("/getUserInfo")
    public Result getUserInfo(HttpSession session) {
        Result result = new Result();
        String email = (String) session.getAttribute("email");
        User user = userService.selectUserByEmail(email);
        if (user != null) {
            result.setMessage("success");
            result.setData(user);
            result.setStatus(Result.RESPONSE_SUCCESS);
        } else {
            result.setMessage("请先登录吧！");
            result.setStatus(Result.RESPONSE_FAIL);
        }
        return result;
    }

    @RequestMapping("/checkRegisterAccount")
    public Result checkRegisterAccount(String account) {
        Result result = new Result();
        if (account.isEmpty()) {
            result.setMessage("账号不可以为空！");
            result.setStatus(Result.RESPONSE_FAIL);
        } else {
            User user = userService.selectUserByUsername(account);
            if (user == null) {
                result.setMessage("此用户不存在");
                result.setStatus(Result.RESPONSE_SUCCESS);
            } else {
                result.setMessage("此用户已存在");
                result.setStatus(Result.RESPONSE_FAIL);
            }
        }

        return result;
    }

    @RequestMapping("/checkRegisterEmail")
    @ResponseBody
    public Result checkRegisterEmail(String email) {
        Result result = new Result();
        if (email.isEmpty()) {
            result.setMessage("邮箱不可以为空！");
            result.setStatus(Result.RESPONSE_FAIL);
        } else {
            User user = userService.selectUserByEmail(email);
            if (user == null) {
                result.setMessage("此邮箱不存在");
                result.setStatus(Result.RESPONSE_SUCCESS);
            } else {
                result.setMessage("此邮箱已存在");
                result.setStatus(Result.RESPONSE_FAIL);
            }
        }
        return result;
    }

    @RequestMapping("/register")
    @ResponseBody
    public Result register(User user, @RequestParam("selectedValue") String selectedValue) {
        User existingUsername = userService.selectUserByUsername(user.getUsername());
        User existingEmail = userService.selectUserByEmail(user.getEmail());

        Result result = new Result();

        if (existingUsername != null || existingEmail != null) {
            result.setStatus(Result.RESPONSE_FAIL);
            result.setMessage("此用户已存在！");
            return result;
        }

        String code = "";
        try {
            ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
            code = valueOperations.get(user.getEmail());
        } catch (Exception e) {
            e.printStackTrace();
            result.setStatus(Result.RESPONSE_EXCEPTION);
            result.setMessage("出错了！请联系管理员 <a href=\"mailto:xb.yang1@outlook.com\">点击这里发送邮件给xb.yang1@outlook.com</a>");
            return result;
        }
        if (user.getValidateCode() != null && user.getValidateCode().equals(code)) {
            user.setEmailStatus(1);
            List<Integer> roleIds = Arrays.stream(selectedValue.split(","))
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
            System.out.println();
            if(userService.insertUser(user, roleIds)){
                result.setStatus(Result.RESPONSE_SUCCESS);
                result.setMessage("注册成功！");
            }else{
                result.setStatus(Result.RESPONSE_FAIL);
                result.setMessage("注册失败！");
            }
        } else {
            result.setStatus(Result.RESPONSE_FAIL);
            result.setMessage("验证码不正确！");
        }

        return result;
    }
    @PostMapping("/checkDbStatus")
    public Result checkDbStatus(){
        return userService.checkDbStatus();
    }


    @PutMapping("/update")
    public Result updateUserInfo(@RequestBody User user,HttpSession session){
        return userService.updateUserInfo(user,session);
    }

    @PostMapping("/changePassword")
    public Result changePassword(@RequestBody ChangePasswordReqVO reqVO,HttpSession session){
        return userService.changePassword(reqVO,session);
    }

    @RequestMapping("/page")
    @RequiresPermissions("system:user:page")
    public Object findPage(User obj,@RequestParam(value = "page",defaultValue = "1")Integer page,
                           @RequestParam(value = "limit",defaultValue = "10")Integer limit) {
        return userService.selectUserList(obj, page, limit);
    }

    @GetMapping("/resetPassword/{id}")
    public Result resetPassword(@PathVariable Integer id){
        return userService.resetPassword(id);
    }

    /**
     * 添加
     */
    @PostMapping
    @RequiresPermissions("system:user:add")
    public Object add(@RequestBody User obj) {
        return userService.insert(obj);
    }

    /**
     * 修改
     */
    @PutMapping
    @RequiresPermissions("system:user:update")
    public Object update(@RequestBody User obj) {
        return userService.update(obj);
    }
    /**
     * 删除
     */
    @DeleteMapping("/{id}")
    @RequiresPermissions("system:user:del")
    public Object del(@PathVariable Integer id) {
        return userService.del(id);
    }

}
